package com.laiketui.mch.controller;

import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.aliyun.tea.Validation;
import com.laiketui.core.domain.Result;
import com.laiketui.core.lktconst.GloabConst;
import com.laiketui.core.utils.tool.DateUtil;
import com.laiketui.domain.mch.MchModel;
import com.laiketui.mch.entity.OrderDetailEntity;
import com.laiketui.mch.util.AmountConverter;
import com.laiketui.mch.util.PriceUtil;
import com.laiketui.order.api.dto.MchOrderDTO;
import com.laiketui.order.api.dto.OrderDetailDTO;
import com.laiketui.order.api.dto.WarehouseDTO;
import com.laiketui.order.api.feign.MchOrderFeign;
import com.laiketui.order.api.page.MyPage;
import com.laiketui.order.api.params.OrderInfoParams;
import com.laiketui.order.api.params.mch.*;
import com.laiketui.root.annotation.HttpApiMethod;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLDecoder;
import java.util.*;

@Api(tags = "订单列表")
@RestController
@RequestMapping("/v2/order")
public class OrderController extends MchBaseController {

    @Autowired
    private MchOrderFeign mchOrderFeign;


    @ApiOperation("订单列表")
    @PostMapping("/list")
    @HttpApiMethod(apiKey = "mch.App.orderV2.list")
    public Result orderList(@Validated MchOrderListParams params){
        MchModel mchModel = currentMch(params);
        params.setMchId(mchModel.getId());
        params.setUserId(mchModel.getUser_id());
        params.setCurrent(params.getPageNum());
        return Result.success(mchOrderFeign.orderList(params));
    }

    @ApiOperation("确认订单")
    @PostMapping("/confirm")
    @HttpApiMethod(apiKey = "mch.App.orderV2.confirm")
    public Result confirm(@Validated MchOrderConfirmParams params){
        MchModel mchModel = currentMch(params);
        params.setMchId(mchModel.getId());
        params.setUserId(mchModel.getUser_id());
        return Result.success(mchOrderFeign.confirm(params));
    }
    @ApiOperation("订单详情")
    @PostMapping("/info")
    @HttpApiMethod(apiKey = "mch.App.orderV2.info")
    public Result info(@Validated MchOrderInfoParams params){
        MchModel mchModel = currentMch(params);
        params.setMchId(mchModel.getId());
        params.setUserId(mchModel.getUser_id());
        return Result.success(mchOrderFeign.orderInfo(params));
    }

    @ApiOperation("备货")
    @PostMapping("/ready")
    @HttpApiMethod(apiKey = "mch.App.orderV2.ready")
    public Result ready(@Validated MchOrderDetailReadyParams params){
        MchModel mchModel = currentMch(params);
        params.setMchId(mchModel.getId());
        params.setUserId(mchModel.getUser_id());
        return Result.success(mchOrderFeign.ready(params));
    }

    @ApiOperation("撤销备货")
    @PostMapping("/revoke")
    @HttpApiMethod(apiKey = "mch.App.orderV2.revoke")
    public Result revoke(@Validated MchOrderDetailReadyParams params){
        MchModel mchModel = currentMch(params);
        params.setMchId(mchModel.getId());
        params.setUserId(mchModel.getUser_id());
        return Result.success(mchOrderFeign.revoke(params));
    }

    @ApiOperation("发货")
    @PostMapping("/send")
    @HttpApiMethod(apiKey = "mch.App.orderV2.send")
    public Result send(@Validated MchOrderSendParams params){
        MchModel mchModel = currentMch(params);
        params.setMchId(mchModel.getId());
        params.setUserId(mchModel.getUser_id());
        return Result.success(mchOrderFeign.send(params));
    }

    @ApiOperation("更新发货单信息")
    @PostMapping("/sendUpdate")
    @HttpApiMethod(apiKey = "mch.App.orderV2.sendUpdate")
    public Result sendUpdate(@Validated MchOrderSendParams params){
        MchModel mchModel = currentMch(params);
        params.setMchId(mchModel.getId());
        params.setUserId(mchModel.getUser_id());
        return Result.success(mchOrderFeign.sendUpdate(params));
    }

    @ApiOperation("获取打标签详情")
    @PostMapping("/printTagInfo")
    @HttpApiMethod(apiKey = "mch.App.orderV2.printTagInfo")
    public Result printTagInfo(@Validated MchOrderDetailParams params){
        MchModel mchModel = currentMch(params);
        params.setMchId(mchModel.getId());
        params.setUserId(mchModel.getUser_id());
        return Result.success(mchOrderFeign.printTagInfo(params));
    }

    @ApiOperation("安排发货")
    @PostMapping("/shipment")
    @HttpApiMethod(apiKey = "mch.App.orderV2.shipment")
    public Result shipment(@Validated MchOrderInfoParams params){
        MchModel mchModel = currentMch(params);
        params.setMchId(mchModel.getId());
        params.setUserId(mchModel.getUser_id());
        return Result.success(mchOrderFeign.shipment(params));
    }

    @ApiOperation("安排发货")
    @PostMapping("/shipmentCancel")
    @HttpApiMethod(apiKey = "mch.App.orderV2.shipmentCancel")
    public Result shipmentCancel(@Validated MchOrderInfoParams params){
        MchModel mchModel = currentMch(params);
        params.setMchId(mchModel.getId());
        params.setUserId(mchModel.getUser_id());
        return Result.success(mchOrderFeign.shipmentCancel(params));
    }


    @PostMapping("/export")
    @HttpApiMethod(urlMapping = {"mch.App.orderV2.export"})
    public Result export(@Validated MchOrderInfoParams params, HttpServletResponse response) {
        Workbook workbook = null;
        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            MchModel mchModel = currentMch(params);
            params.setMchId(mchModel.getId());
            params.setUserId(mchModel.getUser_id());
            MchOrderDTO mchOrderDTO = mchOrderFeign.orderInfo(params);
            workbook = export(mchOrderDTO);

            response.setContentType("application/msexcel");
            String title = String.format("订单%s.xls", params.getOrderNo());
            response.addHeader("Content-Disposition", "filename=" + URLDecoder.decode(title, GloabConst.Chartset.UTF8));
            workbook.write(outputStream);
            return null;
        } catch (Exception e) {

        } finally {
            if (workbook != null) {
                try {
                    workbook.close();
                } catch (IOException e) {

                }
            }
            if(outputStream != null){
                try {
                    outputStream.close();
                } catch (IOException e) {

                }
            }
        }
        return Result.error("导出失败");
    }


    public Workbook export(MchOrderDTO mchOrderDTO) {

        // 模板路径
        String templatePath = "templates/mch_order_detail.xlsx";


        TemplateExportParams params = new TemplateExportParams(templatePath);

        // 创建导出数据
        Map<String, Object> data = new HashMap<>();

        //指定发货时间
        data.put("specifyDeliveryTime", "");
        if (Objects.nonNull(mchOrderDTO.getSpecifyDeliveryTime())) {
            //指定发货时间
            String value = DateUtil.dateFormate(mchOrderDTO.getSpecifyDeliveryTime(), "yyyy/MM/dd");
            data.put("specifyDeliveryTime", value);
        }

        data.put("orderNo",mchOrderDTO.getOrderNo());
        data.put("name",mchOrderDTO.getName());
        data.put("channel",mchOrderDTO.getChannel());
        WarehouseDTO warehouseDTO = mchOrderDTO.getWarehouseDTO();
        data.put("warehouseName", warehouseDTO.getName());
        data.put("warehouseMobile",warehouseDTO.getMobile());
        data.put("warehouseProvice",warehouseDTO.getProvice());
        data.put("warehouseCity",warehouseDTO.getCity());
        data.put("warehouseArea",warehouseDTO.getArea());
        data.put("warehouseAddress",warehouseDTO.getAddress());

        data.put("remark",mchOrderDTO.getRemark());
        data.put("mchRemark",mchOrderDTO.getMchRemark());



        List<OrderDetailDTO> details = mchOrderDTO.getDetails();
        List<OrderDetailEntity> dtOs = new ArrayList<>();
        int nums = 0;
        for (int i = 0; i < details.size(); i++) {
            OrderDetailDTO dto = details.get(i);
            OrderDetailEntity orderDetailEntity = new OrderDetailEntity();
            BeanUtils.copyProperties(dto, orderDetailEntity);
            orderDetailEntity.setSort(i + 1);
            setImageEntity(orderDetailEntity);
            nums += orderDetailEntity.getNum();
            dtOs.add(orderDetailEntity);
        }
        data.put("details", dtOs);
        data.put("num", nums);
        BigDecimal value = mchOrderDTO.getSettlementAmount();
        data.put("settlementAmount", value);
        data.put("totalPriceM", AmountConverter.toChineseUpperCase(value));

        Workbook workbook = ExcelExportUtil.exportExcel(params, data);
        CellStyle style = createStyle(workbook);
        style.setAlignment(HorizontalAlignment.CENTER);

        CellStyle styleRight = createStyle(workbook);
        styleRight.setAlignment(HorizontalAlignment.RIGHT);

        CellStyle styleLeft = createStyle(workbook);
        styleRight.setAlignment(HorizontalAlignment.LEFT);

        Sheet sheet = workbook.getSheetAt(0);
        int lastRowNum = 6 + dtOs.size();

        CellStyle borderStyle = createBorderStyle(workbook);
        lastRowNum++;
        sheet.addMergedRegion(new CellRangeAddress(lastRowNum, lastRowNum, 0, 5));
        Row row = sheet.createRow(lastRowNum);
//        row.setRowStyle(style);
        createCell(row,borderStyle);
        Cell cell1 = row.createCell(0);
        cell1.setCellValue("合计:");
        cell1.setCellStyle(styleRight);


        Cell cell2 = row.createCell(6);
        cell2.setCellValue(nums);
        cell2.setCellStyle(style);
        cell2.getCellStyle().setAlignment(HorizontalAlignment.CENTER);

        row.createCell(7).setCellStyle(style);
        row.createCell(9).setCellStyle(style);
        row.createCell(10).setCellStyle(style);

        Cell cell3 = row.createCell(8);
        cell3.setCellValue(value.toString());
        cell3.setCellStyle(style);
        cell3.getCellStyle().setAlignment(HorizontalAlignment.CENTER);

        lastRowNum++;
        sheet.addMergedRegion(new CellRangeAddress(lastRowNum, lastRowNum, 0, 5));
        sheet.addMergedRegion(new CellRangeAddress(lastRowNum, lastRowNum, 6, 10));
        row = sheet.createRow(lastRowNum);
//        row.setRowStyle(style);
        createCell(row,borderStyle);
        Cell cell = row.createCell(0);
        cell.setCellValue("合计大写总金额:");
        cell.setCellStyle(styleRight);
        cell.getCellStyle().setAlignment(HorizontalAlignment.RIGHT);


        Cell cellM = row.createCell(6);
        cellM.setCellValue(AmountConverter.toChineseUpperCase(value));
        cellM.setCellStyle(styleLeft);

        row.createCell(10).setCellStyle(style);
        row.createCell(8).setCellStyle(style);


        return workbook;
    }

    private static @NotNull CellStyle createStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();
        // 设置边框
        style.setBorderTop(BorderStyle.THIN); // 顶部边框
        style.setBorderBottom(BorderStyle.THIN); // 底部边框
        style.setBorderLeft(BorderStyle.THIN); // 左边边框
        style.setBorderRight(BorderStyle.THIN); // 右边边框
        return style;
    }
    private static void createCell(Row row, CellStyle borderStyle) {
        for (int j=0;j<11;j++){
            row.createCell(j).setCellStyle(borderStyle);
        }
    }
    private static @NotNull CellStyle createBorderStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();
        // 设置边框
        style.setBorderTop(BorderStyle.THIN); // 顶部边框
        style.setBorderBottom(BorderStyle.THIN); // 底部边框
        style.setBorderLeft(BorderStyle.THIN); // 左边边框
        style.setBorderRight(BorderStyle.THIN); // 右边边框
        return style;
    }

    private static void setImageEntity(OrderDetailEntity orderDetailDTO) {
        URL imageUrl = null;
        ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
        try {
            imageUrl = new URL(orderDetailDTO.getImg());
            BufferedImage bufferImg = ImageIO.read(imageUrl);
            ImageIO.write(bufferImg, "jpg", byteArrayOut);
            ImageEntity imageEntity = new ImageEntity(byteArrayOut.toByteArray(), 100, 50);
            orderDetailDTO.setImageEntity(imageEntity);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                byteArrayOut.close();
            } catch (IOException e) {

            }
        }
    }
}
